css: Add API to handle order when printing calc()
authorBenjamin Otte <otte@redhat.com>
Sat, 13 Feb 2016 01:31:47 +0000 (02:31 +0100)
committerBenjamin Otte <otte@redhat.com>
Sat, 13 Feb 2016 03:49:08 +0000 (04:49 +0100)
Also, add some tests and update old ones to print calc() statements
correctly.

gtk/gtkcsscalcvalue.c
gtk/gtkcssdimensionvalue.c
gtk/gtkcssnumbervalue.c
gtk/gtkcssnumbervalueprivate.h
testsuite/css/parser/Makefile.am
testsuite/css/parser/calc.css
testsuite/css/parser/calc.ref.css [new file with mode: 0644]

index 374b23313b5045418f9acaed7b44421f78275def..8df2a67ad91ecda0babb6230d8bb7eeccd3b5899 100644 (file)
@@ -73,6 +73,9 @@ static void
 gtk_css_calc_array_add (GPtrArray *array, GtkCssValue *value)
 {
   gsize i;
+  gint calc_term_order;
+
+  calc_term_order = gtk_css_number_value_get_calc_term_order (value);
 
   for (i = 0; i < array->len; i++)
     {
@@ -84,6 +87,11 @@ gtk_css_calc_array_add (GPtrArray *array, GtkCssValue *value)
           _gtk_css_value_unref (value);
           return;
         }
+      else if (gtk_css_number_value_get_calc_term_order (g_ptr_array_index (array, i)) > calc_term_order)
+        {
+          g_ptr_array_insert (array, i, value);
+          return;
+        }
     }
 
   g_ptr_array_add (array, value);
@@ -235,6 +243,15 @@ gtk_css_value_calc_try_add (const GtkCssValue *value1,
   return NULL;
 }
 
+static gint
+gtk_css_value_calc_get_calc_term_order (const GtkCssValue *value)
+{
+  /* This should never be needed because calc() can't contain calc(),
+   * but eh...
+   */
+  return 0;
+}
+
 static const GtkCssNumberValueClass GTK_CSS_VALUE_CALC = {
   {
     gtk_css_value_calc_free,
@@ -247,7 +264,8 @@ static const GtkCssNumberValueClass GTK_CSS_VALUE_CALC = {
   gtk_css_value_calc_get_dimension,
   gtk_css_value_calc_has_percent,
   gtk_css_value_calc_multiply,
-  gtk_css_value_calc_try_add
+  gtk_css_value_calc_try_add,
+  gtk_css_value_calc_get_calc_term_order
 };
 
 static GtkCssValue *
index f1a4d90bfbd975578b95cc9e5a8bf728b2a61d57..87efb7a6d6999f2c7e0af95b15632d8015652058 100644 (file)
@@ -258,6 +258,33 @@ gtk_css_value_dimension_try_add (const GtkCssValue *value1,
   return gtk_css_dimension_value_new (value1->value + value2->value, value1->unit);
 }
 
+static gint
+gtk_css_value_dimension_get_calc_term_order (const GtkCssValue *value)
+{
+  /* note: the order is alphabetic */
+  guint order_per_unit[] = {
+    /* [GTK_CSS_NUMBER] = */ 0,
+    /* [GTK_CSS_PERCENT] = */ 16,
+    /* [GTK_CSS_PX] = */ 11,
+    /* [GTK_CSS_PT] = */ 10,
+    /* [GTK_CSS_EM] = */ 3,
+    /* [GTK_CSS_EX] = */ 4,
+    /* [GTK_CSS_REM] = */ 13,
+    /* [GTK_CSS_PC] = */ 9,
+    /* [GTK_CSS_IN] = */ 6,
+    /* [GTK_CSS_CM] = */ 1,
+    /* [GTK_CSS_MM] = */ 7,
+    /* [GTK_CSS_RAD] = */ 12,
+    /* [GTK_CSS_DEG] = */ 2,
+    /* [GTK_CSS_GRAD] = */ 5,
+    /* [GTK_CSS_TURN] = */ 15,
+    /* [GTK_CSS_S] = */ 14,
+    /* [GTK_CSS_MS] = */ 8
+  };
+
+  return 1000 + order_per_unit[value->unit];
+}
+
 static const GtkCssNumberValueClass GTK_CSS_VALUE_DIMENSION = {
   {
     gtk_css_value_dimension_free,
@@ -270,7 +297,8 @@ static const GtkCssNumberValueClass GTK_CSS_VALUE_DIMENSION = {
   gtk_css_value_dimension_get_dimension,
   gtk_css_value_dimension_has_percent,
   gtk_css_value_dimension_multiply,
-  gtk_css_value_dimension_try_add
+  gtk_css_value_dimension_try_add,
+  gtk_css_value_dimension_get_calc_term_order
 };
 
 GtkCssValue *
index b7892c760339656fd3a6188167b3c4db05595f01..d685fda902b07aa8d084683e4e82fae2b3a9d5a4 100644 (file)
@@ -78,6 +78,27 @@ gtk_css_number_value_try_add (const GtkCssValue *value1,
   return number_value_class->try_add (value1, value2);
 }
 
+/*
+ * gtk_css_number_value_get_calc_term_order:
+ * @value: Value to compute order for
+ *
+ * Determines the position of @value when printed as part of a calc()
+ * expression. Values with lower numbers are printed first. Note that
+ * these numbers are arbitrary, so when adding new types of values to
+ * print, feel free to change them in implementations so that they
+ * match.
+ *
+ * Returns: Magic value determining placement when printing calc()
+ *     expression.
+ */
+gint
+gtk_css_number_value_get_calc_term_order (const GtkCssValue *value)
+{
+  GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class;
+
+  return number_value_class->get_calc_term_order (value);
+}
+
 GtkCssValue *
 _gtk_css_number_value_new (double     value,
                            GtkCssUnit unit)
index 8e77aaa9f0ca1b48fabf6a15ca5c22377768bc7a..7cb750f87c1e448ed99cb4044e6b04d7f88c86aa 100644 (file)
@@ -49,6 +49,7 @@ struct _GtkCssNumberValueClass {
                                                      double                  factor);
   GtkCssValue *         (* try_add)                 (const GtkCssValue      *value1,
                                                      const GtkCssValue      *value2);
+  gint                  (* get_calc_term_order)     (const GtkCssValue      *value);
 };
 
 GtkCssValue *   _gtk_css_number_value_new           (double                  value,
@@ -65,6 +66,7 @@ GtkCssValue *   gtk_css_number_value_add            (GtkCssValue            *val
                                                      GtkCssValue            *value2);
 GtkCssValue *   gtk_css_number_value_try_add        (const GtkCssValue      *value1,
                                                      const GtkCssValue      *value2);
+gint            gtk_css_number_value_get_calc_term_order (const GtkCssValue *value);
 
 double          _gtk_css_number_value_get           (const GtkCssValue      *number,
                                                      double                  one_hundred_percent);
index 0cc0cce1b8001c7d0c82b0fc700f7b5f45c21af2..fcef07213aae628120ef910abceef9ba9013a3e7 100644 (file)
@@ -227,6 +227,7 @@ test_data = \
         box-shadow.css \
         box-shadow.ref.css \
        calc.css \
+       calc.ref.css \
        calc-simple.css \
        calc-simple.ref.css \
        close-at-end-of-file.css \
index 2c22095c7cad3cd638fca0a6d4c7a26f106297fb..6e7bf54700f9723679e9ad2a42007b43e66948ed 100644 (file)
@@ -2,6 +2,18 @@ a {
   margin-left: calc(3px + 1em);
 }
 
-a {
+b {
   transition-duration: calc(1s - 100ms + -100ms);
 }
+
+c {
+  margin-left: calc(-2px + 1em +    4px);
+}
+
+d {
+  background-size: calc( 100% - 10px );
+}
+
+e {
+  border-left-width: calc(1px + 1px);
+}
diff --git a/testsuite/css/parser/calc.ref.css b/testsuite/css/parser/calc.ref.css
new file mode 100644 (file)
index 0000000..4e858f7
--- /dev/null
@@ -0,0 +1,19 @@
+a {
+  margin-left: calc(1em + 3px);
+}
+
+b {
+  transition-duration: calc(-200ms + 1s);
+}
+
+c {
+  margin-left: calc(1em + 2px);
+}
+
+d {
+  background-size: calc(-10px + 100%);
+}
+
+e {
+  border-left-width: 2px;
+}